﻿using System;
using UnityEngine;
using Object = UnityEngine.Object;

namespace ZFramework.Runtime
{
    public sealed class Entity : MonoBehaviour
    {
        private int _id;
        private string _entityPath;
        private IEntityGroup _entityGroup;
        private EntityLogic _entityLogic;

        public int Id
        {
            get { return _id; }
        }

        public string EntityPath
        {
            get { return _entityPath; }
        }

        public Object Obj
        {
            get { return gameObject; }
        }

        public IEntityGroup EntityGroup
        {
            get { return _entityGroup; }
        }

        public EntityLogic Logic
        {
            get { return _entityLogic; }
        }

        public void OnInit(int entityId, string entityPath, IEntityGroup entityGroup, bool isNewInstance,
            ShowEntityInfo userData)
        {
            _id = entityId;
            _entityPath = entityPath;
            if (isNewInstance)
            {
                _entityGroup = entityGroup;
            }
            else if (_entityGroup != entityGroup)
            {
                Log.Error("Entity OnInit group不同");
                return;
            }

            ShowEntityInfo showEntityInfo = userData;
            Type entityLogicType = showEntityInfo.EntityLogicType;
            if (entityLogicType == null)
            {
                Log.Error("entityLogicType 不能为空");
                return;
            }

            if (_entityLogic != null)
            {
                if (_entityLogic.GetType() == entityLogicType)
                {
                    //初始化过一次就不再走logic的初始化了
                    _entityLogic.enabled = true;
                    return;
                }

                Destroy(_entityLogic);
                _entityLogic = null;
            }

            _entityLogic = gameObject.GetComponent(entityLogicType) as EntityLogic;
            if (_entityLogic == null)
            {
                _entityLogic = gameObject.AddComponent(entityLogicType) as EntityLogic;
            }

            if (_entityLogic == null)
            {
                Log.Error("_entityLogic 添加失败");
                return;
            }

            _entityLogic.OnInit(showEntityInfo.UserData);
        }

        public void OnRecycle()
        {
            _entityLogic.OnRecycle();
            _entityLogic.enabled = false;
            _id = 0;
        }

        public void OnShow(object userData)
        {
            ShowEntityInfo showEntityInfo = (ShowEntityInfo) userData;
            _entityLogic.OnShow(showEntityInfo.UserData);
        }

        public void OnHide(object userData)
        {
            _entityLogic.OnHide(userData);
        }

        public void OnAttached(Entity childEntity, object userData)
        {
            AttachEntityInfo attachEntityInfo = (AttachEntityInfo) userData;
            _entityLogic.OnAttached(((Entity) childEntity).Logic, attachEntityInfo.ParentTransform,
                attachEntityInfo.UserData);
        }

        public void OnDetached(Entity childEntity, object userData)
        {
            _entityLogic.OnDetached(((Entity) childEntity).Logic, userData);
        }

        public void OnAttachTo(Entity parentEntity, object userData)
        {
            AttachEntityInfo attachEntityInfo = (AttachEntityInfo) userData;
            _entityLogic.OnAttachTo(((Entity) parentEntity).Logic, attachEntityInfo.ParentTransform,
                attachEntityInfo.UserData);
            ReferencePool.Release(attachEntityInfo);
        }

        public void OnDetachFrom(Entity parentEntity, object userData)
        {
            _entityLogic.OnDetachFrom(((Entity) parentEntity).Logic, userData);
        }

        public void OnUpdate(float elapseSeconds, float realElapseSeconds)
        {
            _entityLogic.OnUpdate(elapseSeconds, realElapseSeconds);
        }

    }
}
